package es.deusto.ingenieria.aike.time;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import es.deusto.ingenieria.aike.csp.algorithm.CSPAlgorithm;
import es.deusto.ingenieria.aike.csp.formulation.CSPproblem;
import es.deusto.ingenieria.aike.csp.formulation.Variable;

public class TimeProblem extends CSPproblem<Integer> {
		
	private Environment env;
	
	public TimeProblem(Environment env) {
		this.env = env;
		this.createVariables();
		this.createConstraints();
	}
	
	private void createVariables()
	{
		for (int i=0; i<7; i++)
        {
			this.addVariable(new Digit(i, this.createDomain()));
        }
	}
	
	private void createConstraints() {
		Equation equation = new Equation(this.getVariables(), "Equation", env);
		MinutesConstraint minutes = new MinutesConstraint(this.getVariables(), "MinutesConstraint", env);

		for (Variable<Integer> digit : this.getVariables()) {
			digit.addConstraint(equation);			
			if (Integer.valueOf(digit.getName())!=2 && Integer.valueOf(digit.getName())!=3 &&
					Integer.valueOf(digit.getName())!=6)
				digit.addConstraint(minutes);
		}
	}
	
	private List<Integer> createDomain() {
		List<Integer> values = new ArrayList<Integer>(10);		
		
		for (int i=1; i<10; i++) {
			values.add(i);
		}
		return values;
	}
	
	public void solve(CSPAlgorithm<Integer> algorithm) {
		SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss.S");
		Date beginDate = GregorianCalendar.getInstance().getTime();
		System.out.println("\n* Begin '" + algorithm.getClass().getName() + "' (" + formatter.format(beginDate) + ")");		
		boolean solutionFound = algorithm.solve(this);
		Date endDate = GregorianCalendar.getInstance().getTime();		
		System.out.println("* End   '" + algorithm.getClass().getName() + "' (" + formatter.format(endDate) + ")");
		
		long miliseconds = (int) Math.abs(beginDate.getTime() - endDate.getTime());
		long seconds = miliseconds / 1000;
		miliseconds %= 1000;		
		long minutes = seconds / 60;
		seconds %= 60;
		long hours = minutes / 60;
		minutes %= 60;
		
		String time = "\n* Serach lasts: ";
		time += (hours > 0) ? hours + " h " : " ";
		time += (minutes > 0) ? minutes + " m " : " ";
		time += (seconds > 0) ? seconds + "s " : " ";
		time += (miliseconds > 0) ? miliseconds + "ms " : " ";
		
		System.out.println(time);
		
		if (solutionFound) {
			System.out.println("\n* Solution found!!");			
			System.out.println("\n" + this);
		} else {
			System.out.println("\n* Solution not found :-(");
		}
	}
	
}